package com.lsh.ofc.worker.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lsh.base.common.exception.BusinessException;
import com.lsh.ofc.core.constant.Constants;
import com.lsh.ofc.core.entity.*;
import com.lsh.ofc.core.enums.*;
import com.lsh.ofc.core.exception.EC;
import com.lsh.ofc.core.model.PackageCodeBo;
import com.lsh.ofc.core.redis.RedisTemplate;
import com.lsh.ofc.core.service.OfcObdService;
import com.lsh.ofc.core.service.OfcSoService;
import com.lsh.ofc.proxy.model.CreateWmsCloudPackageReqDetail;
import com.lsh.ofc.proxy.model.CreateWmsCloudPackageReqHead;
import com.lsh.ofc.proxy.service.ScServiceProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * 创建SO任务
 *
 * @author huangdong
 * @date 16/9/5
 */
@Component
public class OfcObdBoxPushJob extends AbstractOfcTaskJob {

    @Autowired
    private OfcObdService ofcObdService;

    @Autowired
    private OfcSoService ofcSoService;

    @Autowired
    private ScServiceProxy scServiceProxy;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    protected OfcTaskType getFetchTaskType() {
        return OfcTaskType.OBD_BOX_PUSH;
    }

    @Override
    protected int processTask(OfcTask task) throws BusinessException {

        try {
            String soBillCode = String.valueOf(task.getRefId());
            OfcObdHead filter = new OfcObdHead();
            filter.setSoBillCode(soBillCode);
            OfcObdHead obdHead = ofcObdService.findOne(filter, true);

            OfcSoHead soFilter = new OfcSoHead();
            soFilter.setSoBillCode(soBillCode);
            OfcSoHead soHead = ofcSoService.findOne(soFilter, true);

            if (null == obdHead || soHead == null) {
                return -1;
            }

            if (!FulfillChannel.SAAS_SC.getValue().equals(soHead.getFulfillChannel())) {
                throw EC.ERROR.exception("该订单不是云仓订单，FulfillChannel：" + soHead.getFulfillChannel());
            }

            String ext = obdHead.getExt();
            JSONObject obdExt = JSON.parseObject(ext);
            if (obdExt == null || obdExt.isEmpty()) {
                throw EC.ERROR.exception("该obd订单的ext信息为空");
            }

            // orderType，如果是云仓单，写死2
            CreateWmsCloudPackageReqHead reqHead = this.pushCloudPackageInfo2Sc(obdHead, soHead, 2, obdExt);
//            boolean isSuccess = this.wmsServiceProxy.pushCloudPackageInfo(reqHead);
            boolean isSuccess = this.scServiceProxy.pushCloudPackageInfo(reqHead);
            if (!isSuccess) {
                throw EC.ERROR.exception("云仓订单下发WMS失败，soBillCode 单号 = " + soBillCode);
            } else {
                try {
                    redisTemplate.set(Constants.OBD_BOX_INFO_TO_SC + soBillCode, JSON.toJSONString(reqHead), 604800);
                } catch (Exception e) {
                    logger.error("供商发货OBD下发SC，操作redis异常", e);
                }
            }

            return 1;
        } catch (BusinessException e) {
            logger.error("任务处理失败，任务信息：" + JSON.toJSONString(task), e);
            return -1;
        }
    }

    /**
     * 构建请求Wms包裹数的参数
     *
     * @param obdHead
     * @param orderType
     * @param obdExt
     * @return
     */
    private CreateWmsCloudPackageReqHead pushCloudPackageInfo2Sc(OfcObdHead obdHead, OfcSoHead soHead, Integer orderType, JSONObject obdExt) {
        String soBillCode = obdHead.getSoBillCode();
        Integer supplierId = obdHead.getSupplierId();
        String warehouseCode = soHead.getWarehouseCode();

        Map<Long, Map<BigDecimal, List<OfcSoDetail>>> skuSoDetailsMap = new HashMap<>((int) (soHead.getDetails().size() / 0.75) + 1);
        for (OfcSoDetail detail : soHead.getDetails()) {
            Long skuCode = detail.getSkuCode();
            BigDecimal saleUnit = detail.getGoodsSaleUnit();

            Map<BigDecimal, List<OfcSoDetail>> saleUnitSoDetailsMap = skuSoDetailsMap.get(skuCode);
            if (saleUnitSoDetailsMap == null) {
                saleUnitSoDetailsMap = new HashMap<>(4);
                skuSoDetailsMap.put(skuCode, saleUnitSoDetailsMap);
            }

            List<OfcSoDetail> details = saleUnitSoDetailsMap.get(saleUnit);
            if (details == null) {
                details = new ArrayList<>(4);
                saleUnitSoDetailsMap.put(saleUnit, details);
            }
            details.add(detail);
        }

        Map<String, BigDecimal> aggregateCodeObdDetailsMap = new HashMap<>(); // 提总商品 箱码-obdDetail的map
        for (OfcObdDetail obdDetail : obdHead.getDetails()) {
            JSONObject detailExt = JSON.parseObject(obdDetail.getExt());
            Integer taskModel = detailExt.getInteger("task_model");

            // taskModel = 2；提总作业
            if (taskModel != null && TaskModel.TASK_BOX.getCode().equals(taskModel)) {
                Long skuCode = obdDetail.getSkuCode();
                Map<BigDecimal, List<OfcSoDetail>> unitDetailsMap = skuSoDetailsMap.get(skuCode);

                if (unitDetailsMap == null || unitDetailsMap.isEmpty()) {
                    throw EC.SO_ORDER_IS_ERROR.exception("查询不到该商品的SO详情信息，soBillCode：" + soBillCode + "，skuCode：" + skuCode);
                }

                for (Map.Entry<BigDecimal, List<OfcSoDetail>> entry : unitDetailsMap.entrySet()) {
                    BigDecimal saleUnit = entry.getKey();
                    List<OfcSoDetail> ofcSoDetails = entry.getValue();

                    String packageCode = this.ofcObdService.buildPackageCodes(PackageCodeBo.aggregateTask(supplierId, String.valueOf(obdDetail.getSkuCode()), saleUnit));
                    BigDecimal qty = aggregateCodeObdDetailsMap.get(packageCode);
                    if (qty == null) {
                        // todo：如果箱规是BOX，则传realQty；否则，传qty
                        BigDecimal totalQty = BigDecimal.ZERO;
                        for (OfcSoDetail ofcSoDetail : ofcSoDetails) {
                            BigDecimal skuOrderQty = ofcSoDetail.getSkuOrderQty();
                            JSONObject extJson = JSON.parseObject(ofcSoDetail.getExt());
                            Integer skuDefine = null;
                            if (extJson != null) {
                                skuDefine = extJson.getInteger("sku_define");
                            }

                            if (skuDefine == null) {
                                throw EC.ERROR.exception("云仓订单下发WMS失败，该商品的sku_define为空，soBillCode 单号 = " + soBillCode + "，skuCode：" + skuCode);
                            }

                            if (!SkuDefine.BOX.getCode().equals(skuDefine)) {
                                skuOrderQty = skuOrderQty.divide(ofcSoDetail.getGoodsSaleUnit(), 4, BigDecimal.ROUND_HALF_UP);
                            }

                            totalQty = totalQty.add(skuOrderQty);
                        }

                        aggregateCodeObdDetailsMap.put(packageCode, totalQty);
                    }
                }
            }
        }

        List<CreateWmsCloudPackageReqDetail> details = new ArrayList<>();
        if (!aggregateCodeObdDetailsMap.isEmpty()) {
            for (Map.Entry<String, BigDecimal> entry : aggregateCodeObdDetailsMap.entrySet()) {
                CreateWmsCloudPackageReqDetail detail = new CreateWmsCloudPackageReqDetail();
                detail.setType(2); // 类型：1-包裹、2-按品播种
                detail.setPackageNum(entry.getKey());
                detail.setQty(entry.getValue());
                details.add(detail);
            }
        }

        JSONArray packageCodes = obdExt.getJSONArray(Constants.OBD_D_OBD_PACKAGE_CODES);
        if (packageCodes != null && packageCodes.size() > 0) {
            for (Object packageCode : packageCodes) {
                String packageCodeStr = (String) packageCode;
                if (!packageCodeStr.endsWith("B")) {
                    CreateWmsCloudPackageReqDetail detail = new CreateWmsCloudPackageReqDetail();
                    detail.setPackageNum(this.ofcObdService.buildPackageCodes(PackageCodeBo.normalTask(soBillCode, packageCodeStr)));
                    detail.setQty(BigDecimal.ONE);
                    detail.setType(1); // 类型：1-包裹、2-按品播种
                    details.add(detail);
                }
            }
        }

        CreateWmsCloudPackageReqHead reqHead = new CreateWmsCloudPackageReqHead();
        reqHead.setWarehouseCode(warehouseCode);
        reqHead.setOrderOtherId(soBillCode);
        reqHead.setOrderType(orderType);
        reqHead.setSourceSystem("2");
        reqHead.setDetails(details);

        return reqHead;
    }


    @Override
    protected boolean filterFlag(OfcTask task) {
        return false;
    }

    @Override
    protected List<OfcTask> fetchTasks(OfcTaskType type, Set<OfcTaskStatus> statuses, int shardingCount, List<Integer> shardingItems, int fetchSize) {
        return super.defaultFetchTasks(type, statuses, shardingCount, shardingItems, fetchSize);
    }

}
